package com.business.exam.controller;

import cn.hutool.core.io.resource.ClassPathResource;
import com.business.common.core.controller.BaseController;
import com.business.common.core.domain.AjaxResult;
import com.business.common.core.page.TableDataInfo;
import com.business.common.utils.StringUtils;
import com.business.exam.domain.question.*;
import com.business.exam.service.IQuestionService;
import com.business.exam.utils.ExcelUtilManySheet;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.*;

@RestController("AdminQuestionController")
@RequestMapping(value = "/api/admin/question")
public class QuestionController extends BaseController {

    @Autowired
    private IQuestionService questionService;

    /**
     * 题目详情信息查询
     * @param id
     * @return
     */
    @RequestMapping(value = "/select/{id}", method = RequestMethod.POST)
    public AjaxResult select(@PathVariable Integer id) {
        QuestionEditRequestVM resultData = questionService.getQuestionEditRequestVM(id);
        return AjaxResult.success("操作成功!", resultData);
    }

    /**
     * 题目列表查询
     * @param model
     * @return
     */
    @PreAuthorize("@ss.hasPermi('practice:exam:question:query')")
    @RequestMapping(value = "/page", method = RequestMethod.POST)
    public TableDataInfo pageList(QuestionPageRequestVM model) {
        startPage();
        List<QuestionResponseVM> list = questionService.page(model);
        return getDataTable(list);
    }

    /**
     * 新增、修改题库信息
     * @param model
     * @return
     */
    @PreAuthorize("@ss.hasPermi('practice:exam:question:edit')")
    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    public AjaxResult edit(@RequestBody QuestionEditRequestVM model) {
        if (null == model.getId()) {
            questionService.insertFullQuestion(model, getUserId().intValue());
        } else {
            questionService.updateFullQuestion(model);
        }
        return AjaxResult.success("保存成功!");
    }

    /**
     * 删除题目
     * @param id
     * @return
     */
    @PreAuthorize("@ss.hasPermi('practice:exam:question:remove')")
    @RequestMapping(value = "/delete/{id}", method = RequestMethod.POST)
    public AjaxResult delete(@PathVariable Integer id) {
        Question question = questionService.selectById(id);
        question.setDeleted(true);
        questionService.updateByPrimaryKeySelective(question);
        return AjaxResult.success("删除成功!");
    }

    /**
     * 按照题库分类查询所包含的各题型个数
     * @param model
     * @return
     */
    @RequestMapping(value = "/selectTotalQuestion", method = RequestMethod.POST)
    public AjaxResult selectTotalQuestion(QuestionPageRequestVM model) {
        Map<String,Object> map = questionService.selectTotalQuestion(model);
        return AjaxResult.success(map);
    }

    /**
     * 导入模版下载
     * @param response
     */
    @RequestMapping(value = "/importTemplate", method = RequestMethod.POST)
    public void importTemplate(HttpServletResponse response){
        try {
            // 创建文件输入流对象   读取模板
            ClassPathResource classPathResource = new ClassPathResource("template"+ File.separator+"questionImport.xlsx");
            InputStream inputStream = classPathResource.getStream();
            // 创建工作簿对象
            Workbook workbook = WorkbookFactory.create(inputStream);
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Content-Disposition",
                    "attachment;filename=" + URLEncoder.encode("题目导入模版.xlsx", "UTF-8"));
            OutputStream out = response.getOutputStream();
            workbook.write(out);
            //关闭工作簿和文件输入流
            workbook.close();
            inputStream.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 导入功能实现
     * @param file
     * @param updateSupport
     * @return
     * @throws Exception
     */
    @PreAuthorize("@ss.hasPermi('practice:exam:question:import')")
    @RequestMapping("/importData")
    @ResponseBody
    @ApiOperation("导入数据")
    public AjaxResult importData(@RequestParam MultipartFile file, @RequestParam boolean updateSupport) throws Exception {
        InputStream inputStream = file.getInputStream();
        ExcelUtilManySheet<Object> utilManySheet =new ExcelUtilManySheet<Object>(Object.class);
        Map<String,Class> map =new HashMap<String,Class>();
        // 将每个sheet页的名和需要导入的类对应，加入map集合。
        map.put("单选题",QuestionSingleChoiceVM.class);
        map.put("多选题",QuestionMultipleChoiceVM.class);
        map.put("判断题",QuestionTrueFalseVM.class);
        //map.put("填空题",QuestionGapFillingVM.class);
        map.put("简答题",QuestionShortAnswerVM.class);
        //将每个sheet页转成一个个Object对象数据加入List集合
        List<Object> list = utilManySheet.importExcel(map, inputStream);
        QuestionSingleChoiceVM questionSingleChoice =new QuestionSingleChoiceVM();
        QuestionMultipleChoiceVM questionMultipleChoice =new QuestionMultipleChoiceVM();
        QuestionTrueFalseVM questionTrueFalse =new QuestionTrueFalseVM();
        QuestionGapFillingVM questionGapFilling =new QuestionGapFillingVM();
        QuestionShortAnswerVM questionShortAnswer =new QuestionShortAnswerVM();
        //导入数据条数
        int importNum = 0;
        // 对象集合进行解析 判定是哪个类型进行操作
        for (Object obj:list) {
            Class<?> aClass = obj.getClass();
            QuestionEditRequestVM editRequestVM = new QuestionEditRequestVM();
            List<QuestionEditItemVM> listVm = new ArrayList<QuestionEditItemVM>();
            // 首先判定是否是单选题
            if (aClass.isInstance(questionSingleChoice)){
                //对单选题数据处理
                questionSingleChoice = getQuestionSingleChoiceVM((QuestionSingleChoiceVM) obj, editRequestVM, listVm);
            }else if(aClass.isInstance(questionMultipleChoice)){
                //对多选题数据处理
                questionMultipleChoice = getQuestionMultipleChoiceVM((QuestionMultipleChoiceVM) obj, editRequestVM, listVm);
            }else if(aClass.isInstance(questionTrueFalse)){
                //对判断题数据处理
                questionTrueFalse = getQuestionTrueFalseVM((QuestionTrueFalseVM) obj, editRequestVM, listVm);
            }else if(aClass.isInstance(questionGapFilling)){
                //对填空题数据处理
                questionGapFilling = getQuestionGapFillingVM((QuestionGapFillingVM) obj, editRequestVM, listVm);
            }else if(aClass.isInstance(questionShortAnswer)){
                //对问答题数据处理
                questionShortAnswer = getQuestionShortAnswerVM((QuestionShortAnswerVM) obj, editRequestVM, listVm);
            }
            //导入存在空行，过滤处理excel中空行的问题
            if(StringUtils.isNotEmpty(editRequestVM.getTitle())){
                questionService.insertFullQuestion(editRequestVM, getUserId().intValue());
                importNum = importNum + 1;
            }
        }
        return AjaxResult.success("导入成功"+ importNum + "条数据。");
    }

    /**
     * 简答题数据处理
     * @param obj
     * @param editRequestVM
     * @param listVm
     * @return
     */
    private QuestionShortAnswerVM getQuestionShortAnswerVM(QuestionShortAnswerVM obj, QuestionEditRequestVM editRequestVM, List<QuestionEditItemVM> listVm) {
        QuestionShortAnswerVM questionShortAnswer;
        questionShortAnswer = obj;
        editRequestVM.setQuestionType(5);
        editRequestVM.setSubjectId(questionService.selectKnowledgeIdByContent(questionShortAnswer.getSubjectId()));
        editRequestVM.setTitle(questionShortAnswer.getInfoTextContent());
        editRequestVM.setGradeLevel(questionService.selectCategoryIdByContent(questionShortAnswer.getGradeLevel()));
        editRequestVM.setItems(listVm);
        editRequestVM.setAnalyze(questionShortAnswer.getAnalysis());
        editRequestVM.setCorrectArray(null);
        editRequestVM.setCorrect(questionShortAnswer.getCorrect());
        editRequestVM.setScore(questionShortAnswer.getScore());
        editRequestVM.setDifficult(questionShortAnswer.getDifficult());
        editRequestVM.setItemOrder(null);
        return questionShortAnswer;
    }

    /**
     * 填空题数据处理
     * @param obj
     * @param editRequestVM
     * @param listVm
     * @return
     */
    private QuestionGapFillingVM getQuestionGapFillingVM(QuestionGapFillingVM obj, QuestionEditRequestVM editRequestVM, List<QuestionEditItemVM> listVm) {
        QuestionGapFillingVM questionGapFilling;
        questionGapFilling = obj;
        editRequestVM.setQuestionType(4);
        editRequestVM.setSubjectId(questionService.selectKnowledgeIdByContent(questionGapFilling.getSubjectId()));
        editRequestVM.setTitle(questionGapFilling.getInfoTextContent());
        editRequestVM.setGradeLevel(questionService.selectCategoryIdByContent(questionGapFilling.getGradeLevel()));
        editRequestVM.setItems(listVm);
        editRequestVM.setAnalyze(questionGapFilling.getAnalysis());
        editRequestVM.setCorrectArray(null);
        editRequestVM.setCorrect(questionGapFilling.getOptionA());
        editRequestVM.setScore(questionGapFilling.getScore());
        editRequestVM.setDifficult(questionGapFilling.getDifficult());
        editRequestVM.setItemOrder(null);
        return questionGapFilling;
    }

    /**
     * 判断题数据处理
     * @param obj
     * @param editRequestVM
     * @param listVm
     * @return
     */
    private QuestionTrueFalseVM getQuestionTrueFalseVM(QuestionTrueFalseVM obj, QuestionEditRequestVM editRequestVM, List<QuestionEditItemVM> listVm) {
        QuestionTrueFalseVM questionTrueFalse;
        questionTrueFalse = obj;
        editRequestVM.setQuestionType(3);
        editRequestVM.setSubjectId(questionService.selectKnowledgeIdByContent(questionTrueFalse.getSubjectId()));
        editRequestVM.setTitle(questionTrueFalse.getInfoTextContent());
        editRequestVM.setGradeLevel(questionService.selectCategoryIdByContent(questionTrueFalse.getGradeLevel()));

        if(!"".equals(questionTrueFalse.getOptionA())){
            QuestionEditItemVM vmA = new QuestionEditItemVM();
            vmA.setPrefix("A");
            vmA.setContent(questionTrueFalse.getOptionA());
            listVm.add(vmA);
        }

        if(!"".equals(questionTrueFalse.getOptionB())){
            QuestionEditItemVM vmB = new QuestionEditItemVM();
            vmB.setPrefix("B");
            vmB.setContent(questionTrueFalse.getOptionB());
            listVm.add(vmB);
        }
        editRequestVM.setItems(listVm);

        editRequestVM.setAnalyze(questionTrueFalse.getAnalysis());
        editRequestVM.setCorrectArray(null);
        editRequestVM.setCorrect(questionTrueFalse.getCorrect());
        editRequestVM.setScore(questionTrueFalse.getScore());
        editRequestVM.setDifficult(questionTrueFalse.getDifficult());
        editRequestVM.setItemOrder(null);
        return questionTrueFalse;
    }

    /**
     * 多选题数据处理
     * @param obj
     * @param editRequestVM
     * @param listVm
     * @return
     */
    private QuestionMultipleChoiceVM getQuestionMultipleChoiceVM(QuestionMultipleChoiceVM obj, QuestionEditRequestVM editRequestVM, List<QuestionEditItemVM> listVm) {
        QuestionMultipleChoiceVM questionMultipleChoice;
        questionMultipleChoice = obj;
        editRequestVM.setQuestionType(2);
        editRequestVM.setSubjectId(questionService.selectKnowledgeIdByContent(questionMultipleChoice.getSubjectId()));
        editRequestVM.setTitle(questionMultipleChoice.getInfoTextContent());
        editRequestVM.setGradeLevel(questionService.selectCategoryIdByContent(questionMultipleChoice.getGradeLevel()));
        if(!"".equals(questionMultipleChoice.getOptionA())){
            QuestionEditItemVM vmA = new QuestionEditItemVM();
            vmA.setPrefix("A");
            vmA.setContent(questionMultipleChoice.getOptionA());
            listVm.add(vmA);
        }

        if(!"".equals(questionMultipleChoice.getOptionB())){
            QuestionEditItemVM vmB = new QuestionEditItemVM();
            vmB.setPrefix("B");
            vmB.setContent(questionMultipleChoice.getOptionB());
            listVm.add(vmB);
        }

        if(!"".equals(questionMultipleChoice.getOptionC())){
            QuestionEditItemVM vmC = new QuestionEditItemVM();
            vmC.setPrefix("C");
            vmC.setContent(questionMultipleChoice.getOptionC());
            listVm.add(vmC);
        }

        if(!"".equals(questionMultipleChoice.getOptionD())){
            QuestionEditItemVM vmD = new QuestionEditItemVM();
            vmD.setPrefix("D");
            vmD.setContent(questionMultipleChoice.getOptionD());
            listVm.add(vmD);
        }

        if(!"".equals(questionMultipleChoice.getOptionE())){
            QuestionEditItemVM vmE = new QuestionEditItemVM();
            vmE.setPrefix("E");
            vmE.setContent(questionMultipleChoice.getOptionE());
            listVm.add(vmE);
        }

        if(!"".equals(questionMultipleChoice.getOptionF())){
            QuestionEditItemVM vmF = new QuestionEditItemVM();
            vmF.setPrefix("F");
            vmF.setContent(questionMultipleChoice.getOptionF());
            listVm.add(vmF);
        }
        editRequestVM.setItems(listVm);

        editRequestVM.setAnalyze(questionMultipleChoice.getAnalysis());

        String str = questionMultipleChoice.getCorrect();
        String[] strArray = str.split("");
        editRequestVM.setCorrectArray(Arrays.asList(strArray));

        editRequestVM.setCorrect(null);
        editRequestVM.setScore(questionMultipleChoice.getScore());
        editRequestVM.setDifficult(questionMultipleChoice.getDifficult());
        editRequestVM.setItemOrder(null);
        return questionMultipleChoice;
    }

    /**
     * 选择题数据处理
     * @param obj
     * @param editRequestVM
     * @param listVm
     * @return
     */
    private QuestionSingleChoiceVM getQuestionSingleChoiceVM(QuestionSingleChoiceVM obj, QuestionEditRequestVM editRequestVM, List<QuestionEditItemVM> listVm) {
        QuestionSingleChoiceVM questionSingleChoice;
        questionSingleChoice = obj;
        editRequestVM.setQuestionType(1);
        editRequestVM.setSubjectId(questionService.selectKnowledgeIdByContent(questionSingleChoice.getSubjectId()));
        editRequestVM.setTitle(questionSingleChoice.getInfoTextContent());
        editRequestVM.setGradeLevel(questionService.selectCategoryIdByContent(questionSingleChoice.getGradeLevel()));
        if(!"".equals(questionSingleChoice.getOptionA())){
            QuestionEditItemVM vmA = new QuestionEditItemVM();
            vmA.setPrefix("A");
            vmA.setContent(questionSingleChoice.getOptionA());
            listVm.add(vmA);
        }

        if(!"".equals(questionSingleChoice.getOptionB())){
            QuestionEditItemVM vmB = new QuestionEditItemVM();
            vmB.setPrefix("B");
            vmB.setContent(questionSingleChoice.getOptionB());
            listVm.add(vmB);
        }

        if(!"".equals(questionSingleChoice.getOptionC())){
            QuestionEditItemVM vmC = new QuestionEditItemVM();
            vmC.setPrefix("C");
            vmC.setContent(questionSingleChoice.getOptionC());
            listVm.add(vmC);
        }

        if(!"".equals(questionSingleChoice.getOptionD())){
            QuestionEditItemVM vmD = new QuestionEditItemVM();
            vmD.setPrefix("D");
            vmD.setContent(questionSingleChoice.getOptionD());
            listVm.add(vmD);
        }

        if(!"".equals(questionSingleChoice.getOptionE())){
            QuestionEditItemVM vmE = new QuestionEditItemVM();
            vmE.setPrefix("E");
            vmE.setContent(questionSingleChoice.getOptionE());
            listVm.add(vmE);
        }

        if(!"".equals(questionSingleChoice.getOptionF())){
            QuestionEditItemVM vmF = new QuestionEditItemVM();
            vmF.setPrefix("F");
            vmF.setContent(questionSingleChoice.getOptionF());
            listVm.add(vmF);
        }
        editRequestVM.setItems(listVm);

        editRequestVM.setAnalyze(questionSingleChoice.getAnalysis());
        editRequestVM.setCorrectArray(null);
        editRequestVM.setCorrect(questionSingleChoice.getCorrect());
        editRequestVM.setScore(questionSingleChoice.getScore());
        editRequestVM.setDifficult(questionSingleChoice.getDifficult());
        editRequestVM.setItemOrder(null);
        return questionSingleChoice;
    }

}
